package threadUtils.demo06;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 出现死锁。T-1加锁lock1没有释放，T-2又去走到lock1处，等待lock1释放。T-1走到lock2处，T-2加锁lock2，T-1在等待lock2释放。
 * 出现了相互等待的死锁
 */
public class DeadLockExample {

    final static ReentrantLock t1 = new ReentrantLock();
    final static ReentrantLock t2 = new ReentrantLock();

    private static void l1() {
        t1.lock();
        System.out.println(Thread.currentThread().getName() + " get lock1");
        try {
            try {
                t2.lock();
                System.out.println(Thread.currentThread().getName() + " get lock2");
            } finally {
                t2.unlock();
                System.out.println(Thread.currentThread().getName() + " release lock2");
            }
        } finally {
            t1.unlock();
            System.out.println(Thread.currentThread().getName() + " release lock1");
        }
    }

    private static void l2() {
        t2.lock();
        System.out.println(Thread.currentThread().getName() + " get lock2");
        try {
            try {
                t1.lock();
                System.out.println(Thread.currentThread().getName() + " get lock1");
            } finally {
                t1.unlock();
                System.out.println(Thread.currentThread().getName() + " release lock1");
            }
        } finally {
            t2.unlock();
            System.out.println(Thread.currentThread().getName() + " release lock2");
        }
    }

    public static void main(String[] args) throws InterruptedException {

        new Thread(() -> {
            while (true) {
                l1();
            }
        }, "T-1").start();
        TimeUnit.SECONDS.sleep(3);
        new Thread(() -> {
            while (true) {
                l2();
            }
        }, "T-2").start();
    }

}
